﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace MND.Commands
{
    class CommandBase
    {
        private string name;
        public string Name { get { return name; } }

        private CommandParam[] cParams;
        public CommandParam[] Params { get { return cParams; } }

        private string[] requiredFunctions;
        public string[] RequiredFunctions { get { return requiredFunctions; } }

        private string description;
        public string Description { get { return description; } }

        private CommandScope scope;
        public CommandScope Scope { get { return scope; } }

        private string scenario;
        public string ScenarioString { get { return scenario; } }

        
        public CommandBase(string xmlFilePath)
        {
            XDocument xDoc = XDocument.Load(xmlFilePath);

            // === NAME ===
            name = (from n in xDoc.Descendants("Name")
                    where n.Parent == xDoc.Root
                    select n).First().Value;


            // === PARAMS ===
            cParams = xDoc.Descendants("Params").First().Descendants().Select(s => new CommandParam(s)).ToArray();

            // === BINDINGS ===
            requiredFunctions = xDoc.Descendants("Bindings").First().Descendants("Func").Select(s => s.Value).ToArray();

            // === DESCRIPTION ===
            description = (from desc in xDoc.Descendants("Description")
                              where desc.Parent == xDoc.Root
                              select desc).First().Value;

            // === SCRIPT ===
            scenario = (from mndScript in xDoc.Descendants("Scenario")
                                select mndScript).First().Value;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine(Name.ToUpper());
            sb.AppendLine(String.Format("Składnia: {0} {1}", Name, String.Join<CommandParam>(" ", cParams)));
            sb.AppendLine();
            foreach (CommandParam p in cParams)
            {
                sb.AppendLine(String.Format("{0} - {1}", p.ToString(), p.Description));
            }
            sb.AppendLine();
            sb.AppendLine(Description);

            return sb.ToString();
        }
    }

    public class CommandParam
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsOptional { get; set; }
        public CommandParam(XElement param)
        {
            Name = (from name in param.Descendants("Name")
                    select name).First().Value;
            Description = (from desc in param.Descendants("Description")
                           select desc).First().Value;
            IsOptional = bool.Parse(param.Attribute("isOptional").Value);
        }
        public CommandParam(string name, string description, bool isOptional)
        {
            Name = name;
            Description = description;
            IsOptional = isOptional;
        }

        public override string ToString()
        {
            return IsOptional ? String.Format("[{0}]", Name) : String.Format("<{0}>", Name);
        }
    }

    public enum CommandScope { User, Char }
}
